package com.ldk.base.framework.datasource.generator;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.ldk.base.framework.datasource.DataSourceDriver;;

/**
 * Oracle表实体生成器
 * @author xiangwl
 *
 */
public class OracleEntityGenerator extends EntityGenerator {
	/**
	 * 构造函数
	 * @param serverName
	 * @param portNumber
	 * @param databaseName
	 * @param user
	 * @param password
	 */
	public OracleEntityGenerator(String serverName, int portNumber, String databaseName, String user, String password){
		setServerName(serverName);
		setPortNumber(portNumber);
		setDatabaseName(databaseName);
		setUser(user);
		setPassword(password);
	}
	
	@Override
	protected List<String> getTables() {
		String sql = "select table_name from user_tables;";
		List<String> tables = new ArrayList<String>();
		try{
			Connection conn = getConnection();
			if(conn != null){
				Statement statement =  conn.createStatement();
				ResultSet rs = statement.executeQuery(sql);
				if(rs != null){
					while (rs.next()) {
						tables.add(rs.getString("table_name"));
					}
				}
				statement.close();
				conn.close();
			}
		}
		catch(Exception e){
			logger.error(e.getMessage());
		}
		return tables;
	}

	@Override
	protected List<TableColumn> getTableColums(String table) {
		StringBuilder builder = new StringBuilder();
		builder.append("select t.COLUMN_NAME,t.DATA_TYPE,t.data_precision as NUMERIC_PRECISION,t.nullable as IS_NULLABLE ,c.comments as COLUMN_COMMENT,");
		builder.append(" (SELECT CASE WHEN t.column_name=m.column_name THEN 1 ELSE 0 END FROM DUAL) COLUMN_KEY ");
		builder.append(" FROM user_tab_cols t, user_col_comments c, (select m.column_name from user_constraints s, user_cons_columns m ");
		builder.append(String.format(" where m.table_name='%s' and m.table_name=s.table_name ", table));
		builder.append(" and m.constraint_name=s.constraint_name and s.constraint_type='P') m");
		builder.append(String.format(" WHERE t.table_name='%s' and c.table_name=t.table_name and c.column_name=t.column_name and t.hidden_column='NO'", table));
		builder.append(" order by t.column_id");
		String sql = builder.toString();
		
		List<TableColumn> columns = new ArrayList<TableColumn>();
		try{
			Connection conn = getConnection();
			if(conn != null){
				Statement statement =  conn.createStatement();
				ResultSet rs = statement.executeQuery(sql);
				if(rs != null){
					while (rs.next()) {
						TableColumn column = new TableColumn();
						String columnName = rs.getString("COLUMN_NAME");
						column.setColumnName(columnName);
						String propertyName = underlineToCamel(columnName);
						column.setPropertyName(propertyName);
						String isNUllable = rs.getString("IS_NULLABLE");
						if(!StringUtils.isEmpty(isNUllable) && isNUllable.equalsIgnoreCase("n")){
							column.setIsNullable(false);
						}
						else{
							column.setIsNullable(true);
						}
						String dataType = rs.getString("DATA_TYPE");
						column.setDataType(getColumnDataType(dataType));
						int precision = rs.getInt("NUMERIC_PRECISION");
						column.setPrecision(precision);
						String key = rs.getString("COLUMN_KEY");//PRI
						if(!StringUtils.isEmpty(key) && key.equalsIgnoreCase("1")){
							column.setIsKey(true);
						}
						else{
							column.setIsKey(false);
						}
						//oracle自增不好查 算求了统一为非自增
						column.setIsAutoIncrement(false);
						String comment = rs.getString("COLUMN_COMMENT");
						column.setComment(comment);
						//添加
						columns.add(column);
					}
				}
				statement.close();
				conn.close();
			}
		}
		catch(Exception e){
			logger.error(e.getMessage());
		}
		return columns;
	}

	@Override
	public Connection getConnection() {
		//jdbc:oracle:thin:@118.123.245.160:1521:orcl
		String url = String.format("jdbc:oracle:thin:@%s:%d:%s", 
									getServerName(),getPortNumber(),getDatabaseName());
		Connection conn = null;
		try{
			Class.forName(DataSourceDriver.ORACLE.getNoXADriver());
			conn = DriverManager.getConnection(url, getUser(), getPassword());
		}
		catch(Exception e){
			
		}
		return conn;
	}

	@Override
	protected DBType getDbType() {
		return DBType.ORACLE;
	}

}
